package com.opdar.athena.client.agent.server.tcp;

import com.opdar.athena.client.agent.base.Configuration;
import com.opdar.athena.client.agent.server.IoSession;
import com.opdar.athena.base.Message;
import com.opdar.athena.tcp.TcpRecive;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;

/**
 * Created by shiju on 2017/6/27.
 */
@ChannelHandler.Sharable
public class TcpHandler extends SimpleChannelInboundHandler<Object>{
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        IoSession ioSession = Configuration.getConfiguration().getSession(ctx);
        if(ioSession == null){
            ioSession = new IoSession(ctx);
            Configuration.getConfiguration().setSession(ctx,ioSession);
        }
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
        IoSession ioSession = Configuration.getConfiguration().getSession(ctx);
        if(ioSession != null){
            ioSession.downline();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
        if(o instanceof TcpRecive){
            try {
                IoSession session = Configuration.getConfiguration().getSession(channelHandlerContext);
                session.clearHeartbeat();
                Object result = Configuration.getConfiguration().invokeMessageTypeAction((Message) ((TcpRecive) o).getMessage(), session);
                if(result != null){
                    session.write(((TcpRecive) o).getType(),result);
                }
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }else{
            ReferenceCountUtil.retain(o);
            channelHandlerContext.fireChannelRead(o);
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }
}
